window.onload = function () {
    crystal.run();
};


let crystal = (function () {

    let pixiAppConifg = {
        width:window.innerWidth,
        height:window.innerHeight,
        // forceFXAA:true,
        antialias:true,
        backgroundColor:'0xffffff',
        view:null
    };

    let crystalConifg = {
        lineWidth:null,
        lineHeight:null,
        column:0,
        row:0,
        num:0,
        time:0,
        pointArr:[],
        exploreArr:[],
        app:null,
    };

    let getWidth = function (column) {
        /*
        * Column:想要的列数
        * return: 两点之间的宽度
        * column+1是因为这样可以填满右侧
        * */
        crystalConifg.column = column;
        // crystalConifg.lineWidth = Math.round(pixiAppConifg.width/(column-1));
        crystalConifg.lineWidth = pixiAppConifg.width/(column-1);
    };

    let getHeight = function (row) {
        /*
        * row:想要的行数
        * return: 两点之间的高度
        * column+1是因为这样可以填满底部
        * */
        crystalConifg.row = row;
        // crystalConifg.lineHeight = Math.round(pixiAppConifg.height/(row-1));
        crystalConifg.lineHeight = pixiAppConifg.height/(row-1);
    };

    let initCrystalConifg = function (column,row) {
        /*
        * column:要显示的列数
        * row:要显示的行数
        * */
        getWidth(column);
        getHeight(row);
    };

    let initPixi = function () {
        /*
        * 初始化Pixi数据
        * */
        pixiAppConifg.view = document.getElementById('crystal_canvas');
        crystalConifg.app = new PIXI.Application(pixiAppConifg);
        document.body.appendChild(crystalConifg.app.view);
    };

    let run = function () {
        initCrystalConifg(15,10);
        initPixi();
        allocatePoint();
        generateSkew(crystalConifg.pointArr);
        crystalConifg.app.ticker.add(fill);
    };

    let allocatePoint = function () {
        /*
        * 确定每个点的逻辑位置
        * */
        for(let row=0;row<crystalConifg.row;row++){
            for(let column=0;column<crystalConifg.column;column++){
                if(row===0&&column===0){
                    crystalConifg.pointArr.push({
                        x:0,
                        y:0,
                        position:crystalConifg.pointArr.length,
                        //已访问就为true
                        visited:true,
                        //一个点只能探查位于他上下左右的四个点,探查了的方位被标记为true
                        E:false,
                        S:false,
                        W:false,
                        N:false,
                    });
                }else{
                    // debugger;
                    let position = {
                        x:column===0?0:(crystalConifg.pointArr[crystalConifg.pointArr.length-1].x+crystalConifg.lineWidth),
                        y:row===0?0:(crystalConifg.pointArr[crystalConifg.pointArr.length-crystalConifg.column].y+crystalConifg.lineHeight),
                        position:crystalConifg.pointArr.length,
                        visited:false,
                        E:false,
                        S:false,
                        W:false,
                        N:false
                    };
                    crystalConifg.pointArr.push(position);
                }
            }
        }
        //初始化探索队列,从左上角开始探索
        crystalConifg.exploreArr.push(crystalConifg.pointArr[0]);
        // console.log(crystalConifg);
        // console.log(crystalConifg.pointArr);

    };

    let drawLine = function (m,l) {
        /*
        * m:点的起点
        * l:点的终点
        * 根据输入的点,绘制线
        * */

        let line = new PIXI.Graphics();
        line.lineStyle(3,'0x4b4e4b',1);
        line.moveTo(m.x,m.y);
        line.lineTo(l.x,l.y);
        crystalConifg.app.stage.addChild(line);
    };

    let getIndex = function () {
        /*
        * 随机返回一个探索队列的点
        * */
        // debugger;
        if(crystalConifg.exploreArr.length===1){
            return crystalConifg.exploreArr.pop();
        }
        let index = Math.round(Math.random()*(crystalConifg.exploreArr.length-1));
        let explore = crystalConifg.exploreArr[index];
        if(index!==crystalConifg.exploreArr.length-1){
            crystalConifg.exploreArr[index] = crystalConifg.exploreArr.pop();
        }else{
            crystalConifg.exploreArr.pop();
        }
        return explore;
    };

    let explore = function (point,pointArr,dir) {
        if(pointArr[dir]!==undefined&&dir>=0){
            if(pointArr[dir].visited===false){
                drawLine(point,pointArr[dir]);
                crystalConifg.exploreArr.push(pointArr[dir]);
                pointArr[dir].visited = true;
            }else{
                drawLine(point,pointArr[dir]);
            }
        }
    };

    let fill = function () {
        /*
        * 负责把点之间用线连接起来
        * */
        crystalConifg.time++;
        if(crystalConifg.time%5===0){
            let point = getIndex();
            // console.log(point);
            if(point!==undefined){
                let E = (point.position+1)%crystalConifg.column===0?-1:(point.position+1);
                let S = point.position+crystalConifg.column;
                let W = point.position%crystalConifg.column===0?-1:(point.position-1);
                let N = point.position-crystalConifg.column;
                explore(point,crystalConifg.pointArr,E);
                explore(point,crystalConifg.pointArr,S);
                explore(point,crystalConifg.pointArr,W);
                explore(point,crystalConifg.pointArr,N);
            }
        }
    };

    let generateSkew = function (pointArr) {
        /*
        * pointArr:要偏移的点队列
        * 负责把点的位置进行偏移
        * */
        /*
        * 可以尝试以限定position的方式,然后四条边界的点不改变位置
        * */
        let width = crystalConifg.lineWidth;
        let height = crystalConifg.lineHeight;
        let column = crystalConifg.column;
        for(let i=0;i<(pointArr.length-column);i++){
            let x = pointArr[i].x;
            let y = pointArr[i].y;
            if((x!==0&&y!==0)&&((pointArr[i].position+1)%column)!==0){
                pointArr[i].x = Math.round(Math.random()*(width/2))+x;
                pointArr[i].y = Math.round(Math.random()*(height/2))+y;
            }
        }
        // console.log(pointArr);
    };

    return {
        run:run
    }

})();